package org.wqp.simplemvc.utils;

import java.lang.reflect.*;

/**
 * @author wuqiupeng
 * @date 2018-04-05 16:53
 * @Description 对java反射操作的一些封装
 */

public class BeanUtils {
    /**
     * 实例化一个class
     * @param clazz
     * @param <T>
     */
    public  static<T> T instanceClass(Class<T> clazz) {
        if (!clazz.isInterface()) {
            try {
                return clazz.newInstance();
            } catch ( Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * 通过构造函数实例化
     * @param <T>
     * @param ctor
     * @param args
     * @return
     * @throws IllegalArgumentException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public  static <T> T instanceClass(Constructor<T> ctor, Object... args)
            throws IllegalArgumentException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        makeAccessible(ctor);
        return ctor.newInstance(args);
    }

    /**
     * 查找某几个class的方法
     * @param clazz
     * @param methodName
     * @param paramTypes
     * @return
     */
    public  static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes ){
        try {
            return clazz.getMethod(methodName, paramTypes);
        } catch ( Exception e) {
            //返回共有的方法
            return findDeclaredMethod(clazz, methodName, paramTypes);
        }
    }

    public static  Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        try {
            return clazz.getDeclaredMethod(methodName, paramTypes);
        } catch (Exception e) {
            if (clazz.getSuperclass() != null) {
                return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
            }
            return null;
        }
    }


    public static Method[] findDeclaredMethods(Class<?> clazz) {
        return  clazz.getDeclaredMethods();
    }

    public static  void makeAccessible(Constructor<?> ctor) {
        if ((!Modifier.isPublic(ctor.getModifiers()) ||
        !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
                && !ctor.isAccessible()) {
            ctor.setAccessible(true); //如果是私有的 设置为true使其可以访问
        }
    }


    public  static Field[] findDeclaredFields(Class<?> clazz) {
        return clazz.getDeclaredFields();
    }
}
